/*
 * MainClass.java
 *
 * Created on 8 de Janeiro de 2008, 21:19
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package br.com.cpqd.ssar.posprocessamento;

/**
 *
 * @author igorj
 */

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.StringTokenizer;

class readingFile {
    
    private FileInputStream fileInputStream;
    private FileChannel fileChannel;
    private long fileSize;
    private MappedByteBuffer mBuf;
    private CubeElement[] listCubeElements; 
    private CubeElement nCube;
    private Temporizador t;
    private char[] line = null;
    private String[] vline = null;
    private char temp;
    private int begin = 0; //inicio da linha
    private int cont=0;
    private Double maiorCampo = 0.0;
    private Double menorCampo = 0.0;
    private StringTokenizer st;
    private int numPassos, numMalha, sx, sy ,sz;
    private FileInputStream is;                 // Stream de Entrada
    private BufferedReader br;                  // Buffer de leitura
    private String substring;
    private boolean malha;              //apenas para visualizar a cabe�a
    private Double cor;

    
    
    
    
    
    public readingFile(){
    }
    
    public CubeElement[] reading(String fileName) throws FileNotFoundException, IOException{
        
        
        is = new FileInputStream(fileName + ".config");
        br = new BufferedReader(new InputStreamReader(is));
        String s;
                
        //tempo de processamento
        t = new Temporizador();
        System.out.println("T inicio: " + t.toString());
        
        // lendo arquivo de configuracao 'nome do arquivo.config'
        try {
            
            
            br.readLine(); 
            s = br.readLine(); //le a primeira linha,  numero de passos do FDTD
            vline = split(s);
            //apos dividir a linha, pega o valor 'nmax'
            //System.out.println(vline[2]);
            if(vline.length == 3)
            {     
                if ( vline[2] == "malha")
                    malha = false;
            }
            else{
                malha = true;
            }
            
            numPassos = Integer.valueOf(vline[1]);
            //pegando o valor de 'sx'
            s = br.readLine(); 
            vline = split(s);
            sx = Integer.valueOf(vline[1]); 
            
            //pegando o valor de 'sy'
            s = br.readLine(); 
            vline = split(s);
            sy = Integer.valueOf(vline[1]); 
            
            //pegando o valor de 'sz'
            s = br.readLine(); 
            vline = split(s);
            sz = Integer.valueOf(vline[1]); 
            
            listCubeElements = new CubeElement[numPassos*sy*sx*sz]; 
            System.out.println("Passos de tempo: " + numPassos);
            System.out.println("Dominio: " + sx + ", " + sy + ", " + sz);
            
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        is.close();
        br.close();
        
        // se for arquivo de visualizacao de malha
        if(malha)
        {        
        
            //lendo arquivo de resultados 'arquivo.txt' 
        
            try 
            {
                fileInputStream = new FileInputStream(fileName);
                fileChannel = fileInputStream.getChannel();
                fileSize = fileChannel.size();
                mBuf = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileSize);

                //loop para calcular maior e menor campo do arquivo
                for(int j=0; j<(fileSize); j++)
                {

                    temp = (char)mBuf.get();

                    if ( temp == '\n' )
                    {

                        //tamanho do vetor recebe tamanho de bytes da linha - 1
                        line = new char[cont];

                        mBuf.position(begin);
                        for(int i = 0; i < cont; i++)  //geralmente de 0 a 45
                            line[i] = (char)mBuf.get();    // 44 posicoes

                        //converte a linha de char para string
                        String aux = String.valueOf(line);
                        //divide essa string em x,y,z e campo
                        vline = split(aux);
                        //define maior e menor campo para calcular 'range'
                        if(maiorCampo < Double.valueOf(vline[3]))
                            maiorCampo = Double.valueOf(vline[3]);

                        if(menorCampo > Double.valueOf(vline[3]))
                            menorCampo = Double.valueOf(vline[3]);

                        //pula para proxima linha da leitura do buffer
                        begin = (j+1);
                        mBuf.position(begin);  //continua buffer da onde parou
                        cont = 0;
                    }
                    cont++;

                }

                //mBuf.position(0);           //zera ponteiro do buffer do arquivo
                //begin = 0;
                //cont = 0;
                is = new FileInputStream(fileName);
                br = new BufferedReader(new InputStreamReader(is));

                //leitura do come�o ao fim do arquivo para 1 passo de tempo
                for(int j=0; j<numPassos*sx*sy*sz; j++)
                { // malha: 24x24x24 em 'n' passos

                    //temp = (char)mBuf.get();
                    s = br.readLine();

                   // if ( temp == '\n' ) {

    //                    tamanho do vetor recebe tamanho de bytes da linha - 1
    //                    line = new char[cont];
    //                    mBuf.position(begin);
    //                    for(int i = 0; i < cont; i++)  //geralmente de 0 a 45
    //                        line[i] = (char)mBuf.get();    // 44 posicoes

                        //converte a linha de char para string
                        //split(s);
                        //String aux = String.valueOf(line);
                        //divide essa string em x,y,z e campo
                        vline = split(s);
                        //cria o novo cubo adquirido da n linha
                        cor = setColorField(Double.valueOf(vline[3]));
                       // System.out.println("Cor: " + cor);
    //                    System.out.println("Campo: " + vline[3]);
                        nCube = new CubeElement(Double.valueOf(vline[0]),Double.valueOf(vline[1]), Double.valueOf(vline[2]), cor);
                        //adiciona na lista de cubos
                       // if (Float.valueOf(vline[3]) != 0.0)
                            listCubeElements[j] =  nCube;
                        //pula para proxima linha da leitura do buffer
                        //begin = (j+1);
                       // mBuf.position(begin);  //continua buffer da onde parou
                       // cont = 0;
                    }
                   // cont++;

              //  }

                System.out.println("Maior Campo: " + maiorCampo);
                System.out.println("Menor Campo: " + menorCampo);
                fileChannel.close();
                fileInputStream.close();
                System.out.println("Tempo Arquivo: " + t.toString());

            } catch (IOException exc) {
                System.out.println(exc);
                System.exit(1);
            }
            
        }
        else
        {
            /* neste caso, o arquivo de configura��o n�o tem cont�m a palavra chave 'malha'
             * portanto, trata-se de um arquivo que cont�m a malha da cabe�a humana (do Phantom)
            */
            
            is = new FileInputStream(fileName);
            br = new BufferedReader(new InputStreamReader(is));
            
            System.out.println("passei aqui");
            
           // while((s = br.readLine()) != null )
            for(int i=0; i<1000000; i++)  //este valor pode ser aumentado at� o limite do arquivo lido
            { // malha: 24x24x24 em 'n' passos
                
                s = br.readLine();
                vline = split(s);
                //System.out.println(vline[3]);
                if(Integer.valueOf(vline[3]) != 0) 
                {
                    cor = Double.valueOf(vline[3])/124;
                    nCube = new CubeElement(Double.valueOf(vline[0]),Double.valueOf(vline[1]), Double.valueOf(vline[2]), cor);
                    listCubeElements[i] = nCube;
                }
      
            }
            
        }
        return listCubeElements;
               
        
    }
           
        
    
    
    public String[] split(String sentence) {
        //vetor que contem x,y,z e campo
               
        String[] tokens = null;
        
        String splitPattern = " ";
        
        tokens = sentence.split(splitPattern);
        
        if (tokens == null) {
            String msg = "   NO MATCH: pattern:" + sentence
                    + "\r\n             regex: " + splitPattern;
        } else
            return tokens;

        return tokens;
       
    }
    
    public Double setColorField(Double campo){
        
        Double range;
        Double passo;
        Double cor = 0.0;
        Double RGB = 255.0;
        
        // primeiro caso
        if(  (menorCampo < 0.0) && (maiorCampo > 0.0) && (campo < 0.0)   ) {
            range = Math.abs(menorCampo) + Math.abs(maiorCampo);
            passo = range / RGB; //rangeCor = 255 RGB
            cor = Math.abs(menorCampo - campo)/passo;
            cor = (cor/1000);
        }
        
        if(  (menorCampo < 0.0) && (maiorCampo > 0.0) && (campo > 0.0)   ) {
            range = Math.abs(menorCampo) + Math.abs(maiorCampo);
            passo = range/RGB;
            cor = Math.abs(-menorCampo + campo)/passo;
            cor = (cor/1000);
        }
        
        if(  (menorCampo > 0.0) && (maiorCampo > 0.0) && (campo > 0.0)   ) {
            range = maiorCampo - menorCampo;
            cor = ((Math.abs(campo - menorCampo) * RGB)/range) * (RGB/range);
            cor = (cor/1000);
        }
        return cor;
    }
}




